package com.coovane.bytetrix.service.impl.system;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.coovane.bytetrix.common.enumeration.ErrorCodeEnum;
import com.coovane.bytetrix.common.exception.DuplicateException;
import com.coovane.bytetrix.common.exception.GenericAssert;
import com.coovane.bytetrix.common.exception.GenericException;
import com.coovane.bytetrix.common.exception.ParamIsNullException;
import com.coovane.bytetrix.common.util.ConvertUtils;
import com.coovane.bytetrix.common.util.Copier;
import com.coovane.bytetrix.dao.system.AdminRoleDao;
import com.coovane.bytetrix.domain.system.AdminRole;
import com.coovane.bytetrix.common.model.system.AdminRoleDTO;
import com.coovane.bytetrix.common.model.system.AdminRoleListVO;
import com.coovane.bytetrix.common.model.system.AdminRoleQuery;
import com.coovane.bytetrix.service.system.AdminRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * <p>
 * 管理员角色service实现
 * </p>
 *
 * @author: Hsu
 * @date: 2022/11/30 22:02
 * @copyright: companyName
 * @see
 * @since 1.8
 */
@Slf4j
@Service
public class AdminRoleServiceImpl extends ServiceImpl<AdminRoleDao, AdminRole> implements AdminRoleService {

    /**
     * 列表分页查询
     *
     * @param query
     * @return
     */
    @Override
    public IPage<AdminRoleListVO> pageQuery(AdminRoleQuery query) {
        Page<AdminRole> page = new Page<>(query.getPage(), query.getLimit());
        LambdaQueryWrapper<AdminRole> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(query.getRoleCode())) {
            queryWrapper.like(AdminRole::getRoleCode, query.getRoleCode());
        }
        if (StringUtils.isNotBlank(query.getRoleName())) {
            queryWrapper.like(AdminRole::getRoleName, query.getRoleName());
        }
        if (Objects.nonNull(query.getEnabled())) {
            queryWrapper.eq(AdminRole::getEnabled, query.getEnabled());
        }
        Page<AdminRole> adminRolePage = this.getBaseMapper().selectPage(page, queryWrapper);
        return adminRolePage.convert(adminRole -> ConvertUtils.convert(adminRole, AdminRoleListVO.class));
    }

    /**
     * 新增
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String create(AdminRoleDTO dto) {
        log.info("=====create adminRoleDTO:{}", JSONObject.toJSONString(dto));
        // 校验是否存在逻辑
        assertIfDuplicate(dto);
        AdminRole adminRole = Copier.copy(dto, new AdminRole());
        boolean saveResult = this.save(adminRole);
        GenericAssert.isTrue(saveResult, new GenericException(ErrorCodeEnum.OPERATE_FAILED));
        log.info("=====create adminRole:{}", JSONObject.toJSONString(adminRole));
        return adminRole.getId();
    }

    /**
     * 编辑更新
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String modify(AdminRoleDTO dto) {
        log.info("=====modify adminRoleDTO:{}", JSONObject.toJSONString(dto));
        // 校验是否存在逻辑
        assertIfDuplicate(dto);
        AdminRole adminRole = Copier.copy(dto, new AdminRole());
        boolean updateResult = this.updateById(adminRole);
        GenericAssert.isTrue(updateResult, new GenericException(ErrorCodeEnum.OPERATE_FAILED));
        log.info("=====modify adminRole:{}", JSONObject.toJSONString(adminRole));
        return adminRole.getId();
    }

    /**
     * 获取单个详情
     *
     * @param id
     * @return
     */
    @Override
    public AdminRoleDTO getDetail(String id) {
        GenericAssert.notNull(id, new ParamIsNullException(ErrorCodeEnum.PARAM_IS_NULL));
        AdminRole adminRole = this.getById(id);
        return ConvertUtils.convert(adminRole, AdminRoleDTO.class);
    }

    /**
     * 根据ID逻辑删除
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String deleteById(String id) {
        GenericAssert.notNull(id, new ParamIsNullException(ErrorCodeEnum.PARAM_IS_NULL));
        boolean removeResult = this.removeById(id);
        GenericAssert.isTrue(removeResult, new GenericException(ErrorCodeEnum.OPERATE_FAILED));
        return id;
    }

    /**
     * 校验是否存在重复数据
     * @param dto
     * @return
     */
    @Override
    public void assertIfDuplicate(AdminRoleDTO dto) {
        LambdaQueryWrapper<AdminRole> wrapper = new LambdaQueryWrapper<>();
        // 更新的时候需要判断非当前数据
        if (StringUtils.isNotBlank(dto.getId())) {
            wrapper.ne(AdminRole::getId, dto.getId());
        }
        wrapper.eq(AdminRole::getRoleCode, dto.getRoleCode());
        // 先校验编码是否重复
        boolean exists = this.getBaseMapper().exists(wrapper);
        GenericAssert.isFalse(exists, new DuplicateException(ErrorCodeEnum.PARAM_CODE_DUPLICATE));
        // 清空所有条件
        wrapper.clear();
        // 条件被清空，重新设置条件
        if (StringUtils.isNotBlank(dto.getId())) {
            wrapper.ne(AdminRole::getId, dto.getId());
        }
        wrapper.eq(AdminRole::getRoleName, dto.getRoleName());
        // 再校验名称是否重复
        exists = this.getBaseMapper().exists(wrapper);
        GenericAssert.isFalse(exists, new DuplicateException(ErrorCodeEnum.PARAM_NAME_DUPLICATE));
    }

}
